package framework.interfaces;

import framework.interfaces.Cell;

/**
 * Interface for adding a plugin with custom rules. This lets the parameters be
 * defined, including the properties of the grid and the behavior of the cells
 * for switching states.
 */
public interface RuleSet {

	/**
	 * Gets the next state for a cell
	 * @param active The actively computed cell
	 * @return The next state of active
	 */
	public int getNextState(Cell active);
	
	/**
	 * Determines whether the framework.world should be toroidal or bounded
	 * If framework.world is toroidal, the grid loops around on the borders
	 * If framework.world is bounded, all cells not in the grid are in default state
	 * @return Whether framework.world should be toroidal
	 */
	public boolean getToroidal();
	
	/**
	 * Defines the number of rows in the grid (height)
	 * This should be in the range of [1, 60].
	 * @return The number of rows in the grid
	 */
	public int getGridRows();
	
	/**
	 * Defines the number of columns in the grid (width)
	 * This should be in the range of [1, 60].
	 * @return the number of columns in the grid
	 */
	public int getGridCols();
	
	/**
	 * Defines how many neighbors each cell has
	 * Neighbors are included in the order listed in framework.world.Direction
	 * Therefore, a neighborhood of size 4 will only include the orthogonal directions (N, E, S, W)
	 * A neighborhood of size 2 will only include E, W (for doing a 1D cellular automaton)
	 * @return how many neighbors each cell has
	 */
	public int getNeighborhoodSize();
	
	/**
	 * Defines the number of states each cell can have
	 * @return the number of states each cell can have
	 */
	public int getNumStates();
	
	/**
	 * Defines the default state
	 * This state is used when starting for all cells unless a starting
	 * grid is specified. This state is also used for all cells just past the 
	 * border of the grid when toroidal is disabled (the grid doesn't wrap around)
	 * @return the default state
	 */
	public int getDefaultState();
	
	/**
	 * Defines a starting grid of states to use.
	 * @return a starting grid of states to use or null if all cells should be 
	 * 		   in the default state
	 */
	public int[][] getStartingGrid();
	
	/**
	 * Defines the starting value of the Machine State
	 * @return the starting value of the Machine State
	 */
	public int getStartingMachineState();
	
	/**
	 * Requests a string array that labels each state number with string
	 * label to use in the GUI. This is to make the state picker easier 
	 * to use. 
	 * 
	 * For example: ["On","Off"] would label state 0 as "On", state 1 as
	 * "Off", and all states after with their number.
	 * 
	 * Return null if no state names are going to be used.
	 * 
	 * @return an array of strings such that each string maps to the state
	 * corresponding to its position in the array.
	 */
	
	public String[] getStateNames();
	
}